<template>
    <div class="content">
        <div class="head">
            <span class="head-title">散备件校验</span>
        </div>
        <div class="main">
            <div class="main-left">
                <div class="main-head">
                    <span class="head-span">请选择校验方式:</span>
                    <el-select v-model="checkWay" size="small" placeholder="请选择">
                        <el-option label="手动采码" value="0"></el-option>
                        <el-option label="自动采码" value="1"></el-option>
                    </el-select>
                </div>
                <div class="left-top">
                    <el-checkbox-group v-model="checkList">
                        <el-checkbox label="型号校验" value="型号校验"></el-checkbox>
                    </el-checkbox-group>
                </div>
                <div class="left-form">
                    <el-form
                        label-position="right"
                        label-width="100px"
                        :model="leftForm"
                        ref="leftForm"
                        :rules="leftFormRules"
                        size="small"
                        class="form-content"
                    >
                        <el-form-item label="备货单号" prop="stockUpOdd">
                            <el-input
                                v-model="leftForm.stockUpOdd"
                                placeholder="扫码读取"
                                clearable
                                ref="input1"
                                @keyup.enter.native="inputItem_enter($event, 'stockUpOdd')"
                            ></el-input>
                        </el-form-item>
                        <el-form-item label="产品编号">
                            <el-input
                                v-model="leftForm.productCode"
                                placeholder="自动读取"
                                clearable
                                ref="input2"
                                @keyup.enter.native="inputItem_enter($event, 'productCode')"
                                disabled
                            ></el-input>
                        </el-form-item>
                        <el-form-item label="总数量">
                            <el-input
                                v-model="leftForm.totalNum"
                                placeholder="自动读取"
                                clearable
                                ref="input3"
                                @keyup.enter.native="inputItem_enter($event, 'totalNum')"
                                disabled
                            ></el-input>
                        </el-form-item>
                        <el-form-item label="完成数量">
                            <el-input
                                v-model="leftForm.finishedNum"
                                placeholder="自动读取"
                                clearable
                                ref="input4"
                                @keyup.enter.native="inputItem_enter($event, 'finishedNum')"
                                disabled
                            ></el-input>
                        </el-form-item>
                        <el-form-item label="21条码" prop="barCode_21">
                            <el-input
                                v-model="leftForm.barCode_21"
                                placeholder="扫码读取"
                                clearable
                                ref="input5"
                                @keyup.enter.native="inputItem_enter($event, 'barCode_21')"
                                :disabled="checkWay == '1'"
                            ></el-input>
                        </el-form-item>
                        <el-form-item label="09条码" prop="barCode_09">
                            <el-input
                                v-model="leftForm.barCode_09"
                                placeholder="扫码读取"
                                clearable
                                ref="input6"
                                @keyup.enter.native="inputItem_enter($event, 'barCode_09')"
                                :disabled="false"
                            ></el-input>
                        </el-form-item>
                        <el-form-item label="SN条码" prop="barCode_SN">
                            <el-input
                                v-model="leftForm.barCode_SN"
                                placeholder="扫码读取"
                                clearable
                                ref="input7"
                                @keyup.enter.native="inputItem_enter($event, 'barCode_SN')"
                                :disabled="checkWay == '1'"
                            ></el-input>
                        </el-form-item>
                        <el-form-item label="型号" prop="model">
                            <el-input
                                v-model="leftForm.model"
                                placeholder="扫码读取"
                                clearable
                                ref="input8"
                                @keyup.enter.native="inputItem_enter($event, 'model')"
                                :disabled="!checkList.includes('型号校验') || checkWay == '1'"
                            ></el-input>
                        </el-form-item>
                    </el-form>
                    <div class="form-btn">
                        <el-button type="primary" @click="compelChangeOrder" size="small">强制换单</el-button>
                    </div>
                </div>
                <div class="left-btns" v-show="false">
                    <el-button class="btns-item">取消</el-button>
                    <el-button type="primary" class="btns-item">确定</el-button>
                </div>
            </div>
            <div class="main-right">
                <div class="right-top">
                    <div class="top-switch1" v-if="false">
                        <span class="switch-tip" title="未开启展示全部记录将截取最近的100条记录以提升网页渲染dom速度">展示全部记录</span>
                        <el-switch v-model="isShowAllPassRecords"></el-switch>
                    </div>
                    <i style="cursor: pointer;" class="el-icon-setting" @click="setting_btn" title="设置"></i>
                </div>
                <div class="right-center">
                    <div class="right-box box1">
                        <div class="box-head">
                            <span class="head-title">校验PASS记录:{{ recordPassList.length >= 100 ? '100+' : recordPassList.length}}</span>
                        </div>
                        <div class="box-main">
                            <div class="main-record">
                                <el-timeline :reverse="false">
                                    <el-timeline-item
                                        v-for="(item, index) in recordPassList"
                                        :key="index"
                                        :timestamp="item.time"
                                    >{{ item.info }}</el-timeline-item>
                                </el-timeline>
                            </div>
                        </div>
                    </div>
                    <div class="right-box box2">
                        <div class="box-head">
                            <span class="head-title">校验FAIL记录:{{ recordFailList.length }}</span>
                        </div>
                        <div class="box-main">
                            <div class="main-record">
                                <el-timeline :reverse="false">
                                    <el-timeline-item
                                        v-for="(item, index) in recordFailList"
                                        :key="index"
                                        :timestamp="item.time"
                                    >{{ item.info }}</el-timeline-item>
                                </el-timeline>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="right-btn">
                    <el-button
                        type="primary"
                        size="small"
                        @click="recordExport"
                    >记录导出</el-button>
                </div>
            </div>
        </div>
        <!-- 锁屏 -->
        <el-dialog
            v-if="isLockScreen"
            title="等待质检员解锁后重新扫码"
            width="30%"
            :visible.sync="isLockScreen"
            :close-on-press-escape="false"
            :close-on-click-modal="false"
            :show-close="false"
        >
            <el-form :model="qualitingForm">
                <el-form-item label="账号:">
                    <el-input
                        v-model="qualitingForm.username"
                        :disabled="true"
                        size="small"
                        style="width:20vw;"
                        placeholder="请输入账号"
                    ></el-input>
                </el-form-item>
                <el-form-item label="密码:">
                    <el-input
                        v-model="qualitingForm.password"
                        show-password
                        size="small"
                        ref="lockScreenInput"
                        autofocus
                        @keyup.enter.native="lockScreenConfirm_btn"
                        style="width:20vw;"
                        placeholder="请输入密码"
                    ></el-input>
                </el-form-item>
            </el-form>
            <div slot="footer" class="dialog-footer">
                <el-button @click="lockScreenCancel_btn" size="small">重 置</el-button>
                <el-button type="primary" @click="lockScreenConfirm_btn" size="small">确 定</el-button>
            </div>
        </el-dialog>
        <!-- 设置dialog -->
        <el-dialog title="设置推送RPA主机" :visible.sync="settingFormVisible" width="30%">
            <div class="dialog-checkbox">
                <span class="checkbox-tip" style="margin-right:1vw;">选择产线:</span>
                <el-select v-model="lineCode" size="mini" placeholder="请选择">
                    <el-option
                        v-for="item in lineCodeList"
                        :key="item.id"
                        :label="item.lineName"
                        :value="item.lineCode"
                    ></el-option>
                </el-select>
            </div>
            <div slot="footer" class="dialog-footer">
                <el-button @click="settingFormCancel" size="small">取 消</el-button>
                <el-button type="primary" @click="settingFormConfirm" size="small">确 定</el-button>
            </div>
        </el-dialog>
        <!-- 导出记录dialog -->
        <el-dialog title="记录导出" :visible.sync="exportRecordsDialog" width="40%">
            <el-form :model="exportRecordsDialogForm">
                <el-form-item label="请选择产线" label-width="90px">
                    <el-select v-model="exportRecordsDialogForm.lineCode" size="small" style="width:70%;" placeholder="请选择">
                        <el-option v-for="item,index in lineCodeList" :label="item.lineName" :value="item.lineCode" :key="index"></el-option>
                    </el-select>
                </el-form-item>
                <el-form-item label="日期" label-width="90px">
                    <el-date-picker v-model="exportRecordsDialogForm.date" type="daterange" range-separator="至" start-placeholde="开始日期" end-placeholde="结束日期" value-format="yyyy-MM-dd" size="small" placeholder="选择日期" style="width:60%;"></el-date-picker>
                </el-form-item>
                <el-form-item label="备货单" label-width="90px">
                    <el-input size="small" v-model="exportRecordsDialogForm.stockOrder" placeholder="请输入备货单" clearable style="width:60%;"></el-input>
                </el-form-item>
                <span class="item-span" style="font-size:12px;color:#c0c4cc;">注：产线、日期、备货单非必填项，导出的数据将根据以上约束进行过滤。</span>
            </el-form>
            <div slot="footer" class="dialog-footer">
                <el-button size="small" @click="exportRecordsDialogCancel_btn">取 消</el-button>
                <el-button size="small" type="primary" :loading="exportBtnLoading" @click="exportRecordsDialogConfirm_btn">确 定</el-button>
            </div>
        </el-dialog>
    </div>
</template>

<script>
import { reqProductionOrderDetail, reqRecordsByStockUpOdd, reqRecordsValidate, reqComparisonSysData, reqUnlockScreen, reqIpAddressAndPort, reqCheck21Code, reqCheck09Code, reqExportExcel, reqUserInfo, reqPutRPA, reqStockUpOddFinishedNum, reqSaveResultRecords, reqProductionIPBinds, reqSendRpa, reqSendData, reqSendStockOrder } from "@/api/project.js";
import axios from 'axios';
export default {
    name: "replacementVerify",
    data() {
        var validateIP = (rule, value, callback) => {
            if (value === '') {
                callback(new Error('请输入IP地址'));
            } else {
                if (!this.isValidIPv4(value)) {
                    callback(new Error("IP地址输入有误!"));
                } else {
                    callback();
                }
            }
        };
        var validatePort = (rule, value, callback) => {
            if (value === '') {
                callback(new Error('请输入端口号'));
            } else {
                if (!this.isValidPort(value)) {
                    callback(new Error("端口号输入有误!"));
                } else {
                    callback();
                }
            }
        };
        const validate1 = (rule, value, callback) => {
            if(value.trim() === ''){
                callback(new Error('备货单不能为空'));
            } else {
                callback();
            }
        };
        const validate2 = (rule, value, callback) => {
            let isCheck = this.checkWay == "0" ? true : false;
            const regex = /^[A-Za-z0-9]{20}$/;
            if(value.trim() === '' && isCheck){
                callback(new Error('21条码不能为空'));
            } else if (!regex.test(value) && isCheck){
                callback(new Error('21条码输入有误'));
            } else {
                callback();
            }
        };
        const validate3 = (rule, value, callback) => {
            const regex = /^[a-zA-Z0-9\-\/]+$/;
            if(value.trim() === ''){
                callback(new Error('09条码不能为空'));
            } else if(!regex.test(value)){
                callback(new Error('09码输入有误'));
            } else {
                callback();
            }
        };
        const validate4 = (rule, value, callback) => {
            let isCheck = this.checkWay == "0" ? true : false;
            if(value.trim() === '' && isCheck){
                callback(new Error('SN条码不能为空'));
            } else {
                callback();
            }
        };
        const validate5 = (rule, value, callback) => {
            let isCheckWay = this.checkWay == "0" ? true : false;
            let isCheck = this.checkList.includes("型号校验");
            if(value.trim() === '' && isCheck && isCheckWay){
                callback(new Error('型号码不能为空'));
            } else {
                callback();
            }
        };
        return {
            checkList: [],
            leftForm: {
                stockUpOdd: "",
                productCode: "",
                totalNum: "",
                finishedNum: "",  //完成数量
                barCode_21: "",
                barCode_09: "",
                barCode_SN: "",
                model: ""
            },
            leftFormRules:{
                stockUpOdd:[{validator:validate1,trigger:"blur"}],
                barCode_21:[{validator:validate2,trigger:"blur"}],
                barCode_09:[{validator:validate3,trigger:"blur"}],
                barCode_SN:[{validator:validate4,trigger:"blur"}],
                model:[{validator:validate5,trigger:"blur"}]
            },
            recordPassList: [],
            recordFailList: [],  //{time:"2024-09-03 17:52:00",info:"09条码06200309006/1Y00059429"}
            isLockScreen: false,  //当前是否为锁屏状态
            //质检员的账号密码
            qualitingForm: {
                username: "zhijianyuan",
                password: ""
            },
            //同步设置对话框
            settingFormVisible: false,
            settingForm: {
                ipAddress: "",
                port: "",
                id: ""
            },
            settingRules: {
                ipAddress: [
                    { validator: validateIP, trigger: 'blur' }
                ],
                port: [
                    { validator: validatePort, trigger: 'blur' }
                ]
            },
            timer: null,  //定时器实例
            currentInputFocus: 1,   //当前光标在哪个输入框
            checkWay: "0",  //校验方式:0手动采码 或 1自动采码
            lineCode: "",  //产线编码
            lineCodeList: [],
            isShowAllPassRecords:false,  //是否展示所有的校验通过的记录
            isShowAllFailRecords:false,  //是否展示所有的校验失败的记录
            exportRecordsDialog:false,  //导出记录dialog
            exportBtnLoading: false,
            exportRecordsDialogForm:{
                lineCode:"",
                stockOrder:"",
                date:[]
            }
        }
    },
    mounted() {
        //控制扫码枪读取备货单号
        this.$refs.input1.focus();
        //判断用户身份是否过期
        this.checkIsValidateUser();
        //产线列表
        this.getProductionIPBinds();
        //获取本地存储的相关数据
        this.checkWay = localStorage.getItem("checkWay") || "0";
        const lineInfo = localStorage.getItem("lineInfo") === null ? "" : JSON.parse(localStorage.getItem("lineInfo"));
        //选择性打开dialog选择产线
        if (lineInfo === "") {
            this.settingFormVisible = true;
        } else {
            this.lineCode = lineInfo.lineCode;
        }
    },
    computed:{
        //展示全部校验通过数据 还是 最新的前100条记录
        delRecordPassList(){
            if(!this.isShowAllPassRecords){
                //不展示全部数据
                let len = this.recordPassList.length;
                return len > 100 ? this.recordPassList.slice(0,100) : this.recordPassList;
                //return len > 10 ? this.recordPassList.slice(0,10) : this.recordPassList;
            } else {
                //展示全部数据
                return this.recordPassList;
            }
        }
    },
    beforeDestroy() {
        console.log('组件即将销毁...');
        //清除定时器
        clearInterval(this.timer);
    },
    activated() {
        //组件从缓存中被加载
        console.log('组件从缓存中被加载...');
    },
    deactivated() {
        //组件进入缓存状态
        console.log('组件进入缓存状态...');
        clearInterval(this.timer);
    },
    watch: {
        checkList: {
            handler(newVal, oldVal) {
                //在自动线的模式下,开启型号校验 提示
                if(newVal.includes('型号校验') && this.checkWay == '1'){
                    this.$alert('自动采码将进行型号校验!', '提示', {
                        confirmButtonText: '确定',
                        callback: action => {
                            //确定的回调
                        }
                    });
                }
                //清除表单校验提示
                this.$refs.leftForm.clearValidate();
            }
        },
        //校验方式:手动/自动
        checkWay(newVal, oldVal) {
            //本地存储校验方式
            localStorage.setItem("checkWay", newVal);
            //在自动线的模式下,开启型号校验 提示
            if(newVal == '1' && this.checkList.includes('型号校验')){
                this.$alert('自动采码将进行型号校验!', '提示', {
                    confirmButtonText: '确定',
                    callback: action => {
                        //确定的回调
                    }
                });
            }
            this.$refs.leftForm.clearValidate();
        },
        //检测备货单输入情况
        "leftForm.stockUpOdd": {
            handler(newVal, oldVal) {
                //自动线备货单更改情况下,轮询查询备货单完成数量进行清空
                if (newVal !== oldVal && this.timer !== null) {
                    clearInterval(this.timer);
                }
            }
        },
    },
    methods: {
        /**
            09码 0906200309006/1Y00059429
            21条码 2102510049N0Q9100139 2102510049N0Q9100140
            SN码:HMAA8GR7CJR4N-XNT9   备货单:91370371820001
        */

        //8个输入框的keyup.enter事件
        inputItem_enter: function (event, progress) {
            const _this = this;
            switch (progress) {
                case 'stockUpOdd':
                    //校验备货单
                    this.getProductionOrderDetail();
                    break;
                case 'productCode':
                    break;
                case 'totalNum':
                    break;
                case 'finishedNum':
                    break;
                case 'barCode_21':
                    //校验21码
                    this.invalidateInput5();
                    break;
                case 'barCode_09':
                    //校验09码
                    this.invalidateInput6();
                    break;
                case 'barCode_SN':
                    //校验SN
                    this.invalidateInpu7();
                    break;
                case 'model':
                    //校验型号
                    this.invalidateInpu8();
                    break;
                default:
                    break;
            }
        },

        //检测输入框输入停留时间跳转到下一个光标
        nextInputFocus(current, time) {
            if (this.timer) {
                clearTimeout(this.timer);
            }
            if (current !== 8) {
                this.timer = setTimeout(() => {
                    let input = 'input' + (current + 1);
                    this.$refs[input].focus();
                }, time);
            } else {
                //最后一个输入框:型号码输入停顿后800毫秒后，校验型号码
                this.timer = setTimeout(() => {
                    let input = 'input' + (current);
                    this.$refs[input].blur();
                }, time);
            }
        },
        //输入框的keyup.enter事件,直接下一个输入框的焦点
        nextInputFocus2(current) {
            if (current !== 8) {
                let input = 'input' + (current + 1);
                this.$refs[input].focus();
                this.currentInputFocus = current + 1;  //更新光标位置
            } else {
                //最后一个输入框:型号码输入停顿后800毫秒后，校验型号码
                console.log('最后一个');
                let input = 'input' + (current);
                this.$refs[input].blur();
                this.currentInputFocus = current;  //更新光标位置
            }
        },

        //2.根据备货单号查询产品信息：产品编号和总数量 调用查询完成数量的函数
        async getProductionOrderDetail() {
            //检查备货单是否为空
            if (this.leftForm.stockUpOdd.trim() === "") {
                this.$message({ type: "warning", message: "备货单号不能为空!" });
                if (this.timer !== null) {
                    clearInterval(this.timer);
                }
                return;
            }
            //记录光标指针
            this.currentInputFocus = 1;
            //检查是否选择产线和校验方式
            const checkWay = this.checkWay;
            const lineCode = this.lineCode;
            let lineInfoFilter = this.lineCodeList.filter(item => item.lineCode === this.lineCode);
            if (checkWay === "") {
                this.$message({ type: "warning", message: "请选择校验方式后继续" });
                return;
            }
            if (lineCode === "" || lineInfoFilter.length === 0) {
                this.$message({ type: "warning", message: "请选择产线后继续" });
                return;
            }
            let res = await reqProductionOrderDetail(this.leftForm.stockUpOdd, lineCode);
            if (res.data && res.data.code === 200) {
                if (res.data.data.pass) {
                    //备货单查询成功,单号存在。赋值产品编号和总数量
                    this.leftForm.productCode = res.data.data.productionOrderDetailDTO.mainCode;
                    this.leftForm.totalNum = res.data.data.productionOrderDetailDTO.totalQuantity;

                    //查询已完成的数量:手动线
                    if (this.checkWay === "0") {
                        this.getStockUpOddFinishedNum();
                    } else {
                        //自动线  轮询查询备货单数量 5s 更新一次完成数量
                        if (this.timer !== null) {
                            clearInterval(this.timer);
                        }
                        this.timer = setInterval(() => {
                            this.getStockUpOddFinishedNum();
                        }, 5 * 1000)
                    }

                    //推送备货单到rpa
                    let result = await this.sendStockUpOddToRpa();
                    if (!result) return ;


                    //查询该单号的pass和fail记录
                    this.getRecordsByStockUpOdd(0);
                    this.getRecordsByStockUpOdd(1);
                    //光标跳转
                    if (this.checkWay == "0") {
                        this.$refs.input5.focus();
                        //记录光标指针
                        this.currentInputFocus = 5;
                    } else if (this.checkWay == "1"){
                        //自动线跳到09码输入框
                        this.$refs.input6.focus();
                        //记录光标指针
                        this.currentInputFocus = 6;
                    }
                } else {
                    if(this.checkList.includes("型号校验")){
                        this.controlLockScreen("该备货单不存在!");
                    } else {
                        this.$alert('该备货单不存在!', '提示', { confirmButtonText: '确定',callback: action => {}});
                    }
                    //有定时任务取消掉
                    if (this.timer !== null) {
                        clearInterval(this.timer);
                    }
                }
                console.log('根据备货单号查询产品信息', res.data);
            }
        },
        //根据备货单查询完成数量
        async getStockUpOddFinishedNum() {
            let res = await reqStockUpOddFinishedNum(this.leftForm.stockUpOdd);
            if (res.data.code === 200) {
                this.leftForm.finishedNum = res.data.data || 0;
            }
            console.log('根据备货单查询完成数量', res);
        },
        //校验09码
        validate09Code(code) {
            // 检查条码是否以'09'开头  
            if (!code.startsWith('09')) {
                return false;
            }

            // 判断条码中是否包含'/'  
            const containsSlash = code.includes('/');

            // 如果没有'/'，则验证总长度是否为20位  
            if (!containsSlash) {
                return code.length === 20; // 假设除了'09'开头的2位，后面是8位编码+1位公司代码+9位收据号  
            }

            // 如果有'/'，则验证总长度是否为22位，并且'/'不能是条码的最后一位  
            if (containsSlash && code.length === 24 && code.indexOf('/') !== code.length - 1) {
                // 这里还可以添加更复杂的验证，比如'/'后面的部分是否符合特定格式  
                // 但根据你的描述，只要'/'存在且位置正确，就认为符合规则  
                return true;
            }

            // 如果不满足以上任一条件，返回false  
            return false;
        },
        //校验21码
        validate21Code(code) {
            // 检查条码是否以'21'开头  
            if (!code.startsWith('21')) {
                return false;
            }

            // 检查条码长度是否为20位  
            if (code.length !== 20) {
                return false;
            }

            // 如果以上条件都满足，则返回true  
            return true;
        },
        //与系统基表数据进行比对(扫完SN条码 或者 型号码后)
        async comparisonSysData() {
            const _this = this;
            const { stockUpOdd, barCode_21, barCode_09, barCode_SN, model } = this.leftForm;
            //进行表单全局校验
            if(!this.globalCheck()) {
                this.$message({ type: "warning", message: "输入数据有误,检查后提交!" });
                return ;
            }
            let res = { data: { data: { pass: true } } };
            if (this.checkList.includes('型号校验')) {
                this.$message({ type: "info", message: "正在与系统基表数据比对..." });
                let delModelArr = model.split(" ");
                let delStr = "";
                for(let i = 0; i < delModelArr.length; i ++){
                    if(delModelArr[i].length > delStr.length){
                        delStr = delModelArr[i];
                    }
                }
                let delModel = delStr;
                console.log('处理型号字符串:',delModel);
                try{
                    res = await reqComparisonSysData(barCode_21.substring(2, 10), this.delChildCode(barCode_09), delModel);
                } catch (error) {
                    res = { data: { data: { pass: false } } };
                }
            }
            if (res.data && res.data.data.pass) {
                if (model !== null && model !== undefined && model !== '') {
                    let params = {
                        stockOrderOrTask: this.leftForm.stockUpOdd,
                        parentCode: this.leftForm.barCode_21,
                        childCode: this.leftForm.barCode_09,
                        snCode:this.leftForm.barCode_SN,
                        model: model,
                        lineCode: this.lineCodeList.filter(item => item.lineCode === this.lineCode)[0].lineCode,
                        type: 1,
                        errorMessage: "校验通过!"
                    }
                    reqRecordsValidate(params);
                    this.recordPassOrFail('pass', `型号码${model}`);
                }

                //比对成功:数据同步至华为mes+
                let msg = this.checkList.includes('型号校验') ? '与系统基数据比对成功,正在推送数据...' : '正在推送数据...';
                this.$message({ type: "success", message: msg });
                let queryArr = [this.leftForm.stockUpOdd, this.leftForm.barCode_21, this.leftForm.barCode_09, this.leftForm.barCode_SN];


                //let result = await this.reqSynchronizationData(arr);
                let result = await this.synchronizationData(queryArr);

                //数据推送成功后清除 21码--型号码 if(result)
                if (result) {
                    this.$message({ type: "success", message: "数据同步成功!" });
                    this.leftForm.barCode_21 = "";
                    this.leftForm.barCode_09 = "";
                    this.leftForm.barCode_SN = "";
                    this.leftForm.model = "";
                    //在此将光标跳至21条码处
                    this.$refs.input5.focus();
                    //记录光标指针
                    this.currentInputFocus = 5;
                    //完成数量++
                    //this.leftForm.finishedNum++;
                    this.getStockUpOddFinishedNum();
                    this.$refs.leftForm.clearValidate("barCode_SN");
                    this.$refs.leftForm.clearValidate("model");
                } else {
                    this.$alert('数据同步失败!', '提示', {
                        confirmButtonText: '确定',
                        callback: action => {
                            //数据同步失败
                        }
                    });
                }
            } else {
                if (model !== null && model !== undefined && model !== '') {
                    let params = {
                        stockOrderOrTask: this.leftForm.stockUpOdd,
                        parentCode: this.leftForm.barCode_21,
                        childCode: this.leftForm.barCode_09,
                        snCode:this.leftForm.barCode_SN,
                        model: model,
                        lineCode: this.lineCodeList.filter(item => item.lineCode === this.lineCode)[0].lineCode,
                        type: 0,
                        errorMessage: "校验失败!"
                    }
                    reqRecordsValidate(params);
                    this.recordPassOrFail('fail', `型号码${model}`);
                }
                if(this.checkList.includes("型号校验")){
                    this.controlLockScreen('与系统基数据比对失败,即将锁屏!');
                } else {
                    this.$alert('与系统基数据比对失败!', '提示', { confirmButtonText: '确定',callback: action => {}});
                }
            }
            console.log('获取到型号码后与系统基数据比对', res);
        },
        //校验不通过进行提示 控制锁屏,待质检员解锁后重新扫码
        controlLockScreen(info) {
            this.$message({ type: "warning", message: info });
            //自动采码的情况下：定时查询备货单完成数量 屏幕锁定状态下将定时器取消
            if (this.timer !== null) {
                clearInterval(this.timer);
            }
            setTimeout(() => {
                this.isLockScreen = true;
            }, 100);
            //解锁密码框获取焦点
            setTimeout(() => {
                this.$refs.lockScreenInput.focus();
            },150)
        },
        //本地记录pass or fail记录
        recordPassOrFail(type, progress) {
            const date = new Date();
            const time = date.getFullYear() + "-" + this.addZero(date.getMonth() + 1) + '-' + this.addZero(date.getDate()) + " " + this.addZero(date.getHours()) + ":" + this.addZero(date.getMinutes()) + ":" + this.addZero(date.getSeconds());
            switch (type) {
                case "pass":
                    this.recordPassList.unshift({ time: time, info: progress });
                    if(this.recordPassList.length > 100){
                        this.recordPassList.pop();
                    }
                    break;
                case "fail":
                    this.recordFailList.unshift({ time: time, info: progress });
                    if(this.recordFailList.length > 100){
                        this.recordFailList.pop();
                    }
                    break;
                default:
                    break;
            }
        },
        //备货单校验通过后获取该单号的record包含pass和fail记录
        async getRecordsByStockUpOdd(type) {
            let stockUpOdd = this.leftForm.stockUpOdd;
            //blur事件前再次校验
            if (stockUpOdd === '') return;
            let res = await reqRecordsByStockUpOdd(stockUpOdd, type);
            let list = res.data.data.content;
            let arr = [];
            for (let i = 0; i < list.length; i++) {
                const obj = { time: list[i].createdDate, info: "" };
                if (list[i].parentCode && (list[i].childCode === null || list[i].childCode === '')) {
                    //21码校验成功否
                    obj.info = `21码${list[i].parentCode}`;
                }
                if (list[i].childCode && (list[i].model === null || list[i].model === '')) {
                    //09码校验成功否
                    obj.info = `09码${list[i].childCode}`;
                }
                if (!(list[i].model === null || list[i].model === '')) {
                    //型号码校验成功否
                    obj.info = `型号码${list[i].model}`;
                }
                arr.push(obj);
            }
            if (type === 1) {
                //校验成功的数据
                this.recordPassList = arr;
            } else {
                //校验失败的数据
                this.recordFailList = arr;
            }
            console.log("根据备货单号获取pass或fail记录", res);
        },
        //校验备货单的21条码或09条码是否通过上传请求记录
        async saveRecord(type) {
            let { stockUpOdd, barCode_21, barCode_09 } = this.leftForm;
            const params = { stockOrderOrTask: stockUpOdd || '', parentCode: barCode_21 || '', childCode: barCode_09 || '', type: type || 0 };
            let res = await reqRecordsValidate(params);
            console.log('请求记录备货单21或09条码的pass与fail', res);
        },
        //校验input4输入完成数量的合法性
        invalidateInpu4() {
            let finishedNum = this.leftForm.finishedNum;
            if (finishedNum !== '' && finishedNum >= 0) {
                //合法,继续下一步,扫码21条码
                return;
            } else {
                this.$refs.input4.focus();
                this.$message({ type: "warning", message: "输入的完成数量有误,请重新输入!" });
            }
        },
        //校验21码输入的合法性
        async invalidateInput5() {
            //扫21条码  2102510049N0Q9100139   2102510049N0Q9100140
            if(!this.partFieldCheck(["stockUpOdd","barCode_21"])){
                this.$message({ type: "warning", message: "输入数据有误,检查后提交!" });
                return ;
            }
            let code = this.leftForm.barCode_21;
            /* if (code.trim() === "") return 
            if (!/^[A-Za-z0-9]{20}$/.test(code)) {
                if(this.checkList.includes("型号校验")){
                    this.controlLockScreen(`21码${code}录入不符合规范,请重新录入!`);
                } else {
                    this.$alert('21码录入不符合规范,请重新录入!', '提示', { confirmButtonText: '确定',callback: action => {}});
                }
                this.recordPassOrFail('fail', '扫21或09码顺序不符合规范');
                return ;
            } */
            let checkResult = await this.checkBarcode21AndBarcode09(code, '21');
            if (checkResult) {
                await this.saveRecord(1);
                this.recordPassOrFail('pass', `21条码${code}`);
                //继续扫09条码,光标向下
                this.$refs.input6.focus();
                //记录光标指针
                this.currentInputFocus = 6;
            } else {
                this.saveRecord(0);
                if(this.checkList.includes("型号校验")){
                    this.controlLockScreen(`21码${code}校验失败，即将锁屏!`);
                } else {
                    this.$alert('21码校验失败!', '提示', { confirmButtonText: '确定',callback: action => {}});
                }
                this.recordPassOrFail('fail', `21条码${code}`);
            }
        },
        //校验09码的输入合法性
        async invalidateInput6() {
            //09条码  09 06200309006/1Y00059429    0999100BBN1Y00059747
            if(!this.partFieldCheck(["stockUpOdd","barCode_21","barCode_09"])){
                this.$message({ type: "warning", message: "输入数据有误,检查后提交!" });
                return ;
            }
            let code = this.leftForm.barCode_09;
            //请求校验09码
            let checkResult = await this.checkBarcode21AndBarcode09(code, '09');
            if (checkResult) {
                this.leftForm.barCode_09 = code;
                await this.saveRecord(1);
                //本地记录
                this.recordPassOrFail('pass', `09条码${code}`);
                //校验成功后,(光标向下:扫SN条码进行关联)|(自动线上传备货单和09码进行绑定)
                if(this.checkWay === '0'){
                    this.$refs.input7.focus();
                    //记录光标指针
                    this.currentInputFocus = 7;
                } else {
                    //自动线执行此操作
                    let lineCode = this.lineCodeList.filter(item => item.lineCode === this.lineCode)[0].lineCode;
                    let stockOrder = this.leftForm.stockUpOdd;
                    let childCode = this.leftForm.barCode_09;
                    let isOpenModelCheck = this.checkList.includes("型号校验")? true : false;
                    if(lineCode === ""){
                        return this.$message({type:"warning",message:"请选择产线!"});
                    }
                    if(stockOrder === "" || childCode === ""){
                        return this.$message({type:"warning",message:"备货单货09码不能为空!"});
                    }
                    reqSendData(lineCode,stockOrder,childCode,isOpenModelCheck)
                        .then(res => {
                            if(res.data.code === 200){
                                this.$message({type:"success",message:"备货单、09码已上传绑定!"});
                            }
                        })
                        .catch(error => {
                            this.$message({type:"error",message:error});
                        })
                } 
            } else {
                this.saveRecord(0);
                if(this.checkList.includes("型号校验")){
                    this.controlLockScreen(`09码${code}校验失败,即将锁屏!`);
                } else {
                    this.$alert('09码校验失败!', '提示', { confirmButtonText: '确定',callback: action => {}});
                }
                this.recordPassOrFail('fail', `09条码${code}`);
            }
        },
        //校验SN码合法性
        async invalidateInpu7() {
            if(!this.partFieldCheck(["stockUpOdd","barCode_21","barCode_09","barCode_SN"])){
                this.$message({ type: "warning", message: "输入数据有误,检查后提交!" });
                return ;
            }
            let code = this.leftForm.barCode_SN;
            //判断不需要输入型号码，直接在此进行基表数据的比对
            if (!this.checkList.includes("型号校验")) {
                this.comparisonSysData();
            } else {
                //继续下一步,光标向下,扫型号码
                this.$refs.input8.focus();
                //记录光标指针
                this.currentInputFocus = 8;
            }
        },
        //校验型号码的合法性
        async invalidateInpu8() {
            let model = this.leftForm.model;
            if(!this.partFieldCheck(["stockUpOdd","barCode_21","barCode_09","barCode_SN","model"])){
                this.$message({ type: "warning", message: "输入数据有误,检查后提交!" });
                return ;
            }
            //发请求:比对基表数据
            //model:HMAA8GR7CJR4N-XN TG AC 352
            this.comparisonSysData();
        },
        //发请求校验21码和09码
        async checkBarcode21AndBarcode09(barCode, type) {
            if (type === '21') {
                let code = barCode.substring(2, barCode.length).substring(0, 8);
                let res = await reqCheck21Code(code);
                console.log('请求校验21码', res);
                if (res.data && res.data.data.pass) {
                    return true;
                }
            } else if (type === '09') {
                let res = await reqCheck09Code(this.delChildCode(barCode));
                console.log('校验09码', res);
                if (res.data && res.data.data.pass) {
                    return true;
                }
            }
            return false;
        },
        //强制换单
        compelChangeOrder() {
            //强制换单锁屏
            this.controlLockScreen("强制换单");
            //清空散备件页面的表单数据
            this.leftForm.stockUpOdd = "";
            this.leftForm.productCode = "";
            this.leftForm.totalNum = "";
            this.leftForm.finishedNum = "";
            this.leftForm.barCode_09 = "";
            this.leftForm.barCode_21 = "";
            this.leftForm.barCode_SN = "";
            this.leftForm.model = "";
            this.qualitingForm.password = "";
            this.recordPassList = [];
            this.recordFailList = [];
        },
        //锁屏界面点击解锁和重置按钮
        async lockScreenConfirm_btn() {
            const _this = this;
            if (this.qualitingForm.password === '') {
                return this.$message({ type: "warning", message: "请输入密码!" });
            }
            let res = await reqUnlockScreen(this.qualitingForm.password);
            if (res.data.data.id) {
                //质检员密码正确
                this.$message({ type: "success", message: "屏幕已解锁!" });
                //清空散备件页面的表单数据
                /* _this.leftForm.stockUpOdd = "";
                _this.leftForm.productCode = "";
                _this.leftForm.totalNum = "";
                _this.leftForm.finishedNum = "";
                _this.leftForm.barCode_09 = "";
                _this.leftForm.barCode_21 = "";
                _this.leftForm.barCode_SN = "";
                _this.leftForm.model = "";
                _this.qualitingForm.password = "";
                _this.recordPassList = [];
                _this.recordFailList = []; */
                //跳转到散备件数据录入界面
                setTimeout(() => {
                    this.isLockScreen = false;
                    this.qualitingForm.password = "";
                    //聚集光标
                    //this.$refs[`input${this.currentInputFocus}`].focus();
                }, 500)
            } else {
                this.$message({ type: "error", message: "密码输入错误，请重试!" });
            }
            console.log('质检员输入密码解锁屏幕', res);
        },
        lockScreenCancel_btn() {
            this.qualitingForm.password = "";
            // this.isLockScreen = false;
            this.$refs.lockScreenInput.focus();
        },
        //补零函数
        addZero(val) {
            return val >= 10 ? val : ('0' + val);
        },
        //设置确定图标
        setting_btn() {
            this.settingFormVisible = true;
        },
        //设置确定按钮
        async settingFormConfirm() {
            if (this.lineName === "") return;
            this.$message({ type: "success", message: "产线选择成功!" });
            setTimeout(() => {
                this.settingFormVisible = false;
            }, 200)
            //本地存储产线信息
            let lineInfo = this.lineCodeList.filter(item => item.lineCode === this.lineCode)[0];
            localStorage.setItem("lineInfo", JSON.stringify(lineInfo));

            //备货单输入框获取焦点
            this.$refs.input1.focus();
        },
        //设置取消按钮
        settingFormCancel() {
            this.settingFormVisible = false;
            //备货单输入框获取焦点
            this.$refs.input1.focus();
        },
        //最终数据同步 queryArr:[21条码,09条码,sn条码,型号码]
        async reqSynchronizationData(queryArr) {
            let checkWay = this.checkWay;  //"0"-手动  "1"-自动
            if (checkWay === "0") {
                let url = "http://192.168.1.10:1246/write?";
                if (queryArr.length === 3) {
                    url = url + 'parentCode=' + queryArr[0] + "&childCode=" + queryArr[1] + "&snCode=" + queryArr[2];
                } else {
                    url = url + 'stockOrder=' + queryArr[0] + '&parentCode=' + queryArr[1] + "&childCode=" + queryArr[2] + "&snCode=" + queryArr[3];
                }
                const response = await axios.get(url);
                console.log('推送到本地主机', response);
                if (response.data.code === 200) {
                    const { stockUpOdd, barCode_21, barCode_09, barCode_SN } = this.leftForm;
                    reqSaveResultRecords(stockUpOdd, barCode_21, barCode_09, barCode_SN);
                    return true;
                }
                return false;
            } else if (checkWay === "1") {
                //推送到远程
                if (queryArr.length === 4) queryArr.splice(0, 1);
                let response = await reqPutRPA(queryArr[0], queryArr[1], queryArr[2], this.leftForm.stockUpOdd);
                console.log('推送到远程主机', response);
                if (response.data.code === 200) {
                    return true;
                }
                return false;
            }
        },
        async synchronizationData(queryArr) {
            let lineCode = this.lineCodeList.filter(item => item.lineCode === this.lineCode)[0].lineCode;
            let res = await reqSendRpa(queryArr[0], queryArr[1], queryArr[2], queryArr[3], lineCode);
            console.log('手动采码数据同步到rpa', res);
            if (res.data.code === 200) {
                return true;
            }
            return false;
        },
        // IPV4格式校验
        isValidIPv4(ip) {
            const pattern = /^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
            return pattern.test(ip);
        },
        // 校验端口号
        isValidPort(port) {
            const portNum = Number.parseInt(port, 10);
            return Number.isInteger(portNum) && portNum >= 1 && portNum <= 65535;
        },
        //记录导出按钮
        async recordExport() {
            this.exportRecordsDialog = true;
        },
        //判断当前用户身份是否过期
        async checkIsValidateUser() {
            let res = await reqUserInfo();
            let isExpired = res.data.data.isExpired;
            if (isExpired) {           
                const routeList = this.$router.options.routes;
                let isHasSettingPermission = routeList.findIndex(item => item.path === '/setting');
                console.log('是否找到了该路由',isHasSettingPermission);
                if(isHasSettingPermission !== -1){
                    //跳转路由,打开重置密码框
                    this.$router.push({path:"/setting"});
                } else {
                    //无质检员设置权限
                    this.$alert('质检员身份过期，当前用户无质检员设置权限，请联系质检员进行密码重置！（质检员密码重置后刷新页面即可关闭此提示）', '提示', {
                        showConfirmButton:true,
                        showClose:false,
                        confirmButtonText: '刷新页面',
                        beforeClose: (action,instance,done) => {
                            //页面刷新
                            location.reload();
                        }
                    });
                }
            }
        },
        //获取所有的产线列表接口
        async getProductionIPBinds() {
            let res = await reqProductionIPBinds();
            if (res.data.code === 200) {
                let list = res.data.data.map(item => {
                    return { id: item.id, lineCode: item.lineCode, lineIp: item.lineIp, lineName: item.lineName };
                })
                this.lineCodeList = list;
            }
            console.log('产线列表数据', res);
        },
        //推送备货单到rpa
        async sendStockUpOddToRpa() {
            let lineCode = this.lineCode;
            try {
                const response = await reqSendStockOrder(this.leftForm.stockUpOdd, lineCode);
                console.log('备货单推送api', response);
                if (response.data.code === 200) {
                    this.$message({ type: "success", message: "备货单推送成功!" });
                    return true;
                }
            } catch (error) {
                this.$message({ type: "error", message: '备货单推送失败' + error });
                return false;
            }
        },
        //表单校验
        globalCheck() {
            let checkResult = false;
            this.$refs.leftForm.validate((valid) => {
                checkResult = valid;
            });
            return checkResult;
        },
        partFieldCheck(fieldList){
            let checkedResultList = [];
            this.$refs.leftForm.validateField(fieldList,(result) => {
                if(result === ""){
                    checkedResultList.push(true);
                } else {
                    checkedResultList.push(false);
                }
            })
            return checkedResultList.every(e => e === true);
        },
        //导出dialog的确定与取消按钮
        exportRecordsDialogCancel_btn(){
            this.exportRecordsDialog = false;
            this.exportRecordsDialogForm.lineCode = "";
            this.exportRecordsDialogForm.stockOrder = "";
            this.exportRecordsDialogForm.date = [];
        },
        async exportRecordsDialogConfirm_btn(){
            let { lineCode, stockOrder, date } = this.exportRecordsDialogForm;
            const params = {
                stockOrder:stockOrder,
                lineCode:lineCode,
                startDate:date[0],
                endDate:date[1]
            }
            this.exportBtnLoading = true;  //导出按钮loading
            let res = await reqExportExcel(params);
            if (res.status === 200) {
                let blob = res.data;
                let url = window.URL.createObjectURL(blob, { type: 'application/zip' });
                const aLink = document.createElement('a');
                aLink.href = url;
                let timestamp = new Date().getTime();
                aLink.setAttribute('download', '散备件校验记录_' + timestamp);
                document.body.appendChild(aLink);
                aLink.click();
                document.body.removeChild(aLink);
                this.$message.success('导出成功!');
                this.exportRecordsDialogCancel_btn();
                this.exportBtnLoading = false;
            } else {
                this.$message.error('导出失败,请重试!');
                this.exportBtnLoading = false;
            }
        },
        //对09码进行处理
        delChildCode(code){
            let temp = "";
            let delCode = /^[pP]/.test(code) ? code.substring(1, code.length) : code.substring(2, code.length);
            if (delCode.includes('/')) {
                temp = delCode.substring(0, 12);
            } else {
                temp = delCode.substring(0, 8);
            }
            return temp;
        }
    }
}
</script>

<style lang='scss' scoped>
.content {
    width: 100%;
    height: calc(100vh - 50px);
    user-select: none;
    .head {
        width: 100%;
        height: 6%;
        display: flex;
        justify-content: center;
        align-items: center;
        text-align: center;
        background-color: #02b2fd;
        font-size: 1.5vw;
        color: #fff;
    }
    .main {
        width: 100%;
        height: 94%;
        padding: 0.5%;
        box-sizing: border-box;
        display: flex;
        .main-left {
            box-sizing: border-box;
            margin: 1% 0;
            flex: 1;
            .main-head {
                width: 100%;
                padding: 0 0 5vh 4vw;
                box-sizing: border-box;

                .head-span {
                    margin-right: 1vw;
                    font-size: 14px;
                    font-weight: 530;
                }
            }
            .left-top {
                margin-left: 3vw;
                margin-bottom: 3vh;
            }
            .left-form {
                display: flex;
                justify-content: space-evenly;
                .form-content {
                    width: 50%;
                }
                .form-btn {
                    width: 30%;
                }
            }
            .left-btns {
                margin: 2vw 0;
                display: flex;
                box-sizing: border-box;
                justify-content: center;
                .btns-item {
                    margin: 0 3vw;
                }
            }
        }
        .main-right {
            box-sizing: border-box;
            flex: 1;
            display: flex;
            flex-direction: column;
            .right-top {
                height: 5vh;
                display: flex;
                justify-content: flex-end;
                .top-switch1{
                    display: flex;
                    align-items: center;
                    font-size: 0.9vw;
                    .switch-tip{
                        margin-right: 5px;
                        cursor: pointer;
                        color: #9195a3;
                    }
                }
            }
            .right-center {
                display: flex;
                justify-content: space-between;
                align-items: center;
                .right-box {
                    width: 20vw;
                    height: 75vh;
                    border: 1px solid #dbdbdb;
                    .box-head {
                        width: 20vw;
                        height: 4vh;
                        display: flex;
                        justify-content: center;
                        align-items: center;
                        background-color: #02b2fd;
                        font-size: 1vw;
                        color: #fff;
                    }
                    .box-main {
                        width: 20vw;
                        height: 70vh;
                        display: flex;
                        justify-content: center;
                        align-items: center;
                        .main-record {
                            width: 20vw;
                            height: 96%;
                            padding: 1vh 1vw;
                            box-sizing: border-box;
                            overflow: auto;
                            ::v-deep .el-timeline {
                                font-size: 12px;
                            }
                            ::v-deep .el-timeline-item__timestamp {
                                font-size: 10px;
                            }
                        }
                    }
                }
            }
            .right-btn {
                padding: 5px 0;
                box-sizing: border-box;
                display: flex;
                justify-content: flex-end;
            }
        }
    }
}
</style>